<script setup>
import { ref, watch, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import request from '@/utils/request'

const props = defineProps({
  modelValue: { type: String, default: '' },
  placeholder: { type: String, default: '在此输入内容...' },
  height: { type: String, default: '240px' },
})
const emit = defineEmits(['update:modelValue'])

const editorRef = ref(null)
const fileInputRef = ref(null)

function setHtml(html) {
  if (editorRef.value) {
    editorRef.value.innerHTML = html || ''
  }
}

function getHtml() {
  return editorRef.value?.innerHTML || ''
}

watch(
  () => props.modelValue,
  (val) => {
    // 外部更改时更新编辑器（避免循环）
    if (val !== getHtml()) setHtml(val || '')
  },
  { immediate: true }
)

function exec(cmd, value = null) {
  document.execCommand(cmd, false, value)
  emit('update:modelValue', getHtml())
}

function handleInput() {
  emit('update:modelValue', getHtml())
}

function openLink() {
  const url = window.prompt('输入链接地址：', 'https://')
  if (!url) return
  exec('createLink', url)
}

function clearFormat() {
  exec('removeFormat')
}

function insertImage(url) {
  if (!url) return
  const img = document.createElement('img')
  img.src = url
  img.style.maxWidth = '100%'
  const sel = window.getSelection()
  if (sel && sel.rangeCount > 0) {
    const range = sel.getRangeAt(0)
    range.insertNode(img)
  } else {
    editorRef.value?.appendChild(img)
  }
  emit('update:modelValue', getHtml())
}

async function uploadImage(file) {
  const formData = new FormData()
  formData.append('file', file)
  try {
    const res = await request.post('/file/rich-text-image', formData, {
      headers: { 'Content-Type': 'multipart/form-data' },
    })
    if (String(res.code) === '200') {
      insertImage(res.data)
      ElMessage.success('图片已插入')
    } else {
      ElMessage.error(res.msg || '上传失败')
    }
  } catch (e) {}
}

function triggerUpload() {
  fileInputRef.value?.click()
}

function handleFileChange(e) {
  const file = e.target.files?.[0]
  if (file) uploadImage(file)
  e.target.value = ''
}

onMounted(() => {
  // 初始内容
  setHtml(props.modelValue || '')
})
</script>

<template>
  <div class="rte">
    <div class="rte-toolbar">
      <el-button-group>
        <el-button size="small" @click="exec('bold')">加粗</el-button>
        <el-button size="small" @click="exec('italic')">斜体</el-button>
        <el-button size="small" @click="exec('underline')">下划线</el-button>
        <el-button size="small" @click="exec('insertOrderedList')">有序</el-button>
        <el-button size="small" @click="exec('insertUnorderedList')">无序</el-button>
        <el-button size="small" @click="openLink">链接</el-button>
        <el-button size="small" @click="triggerUpload">插入图片</el-button>
        <el-button size="small" @click="clearFormat">清除格式</el-button>
      </el-button-group>
      <input ref="fileInputRef" type="file" accept="image/*" class="hidden-file" @change="handleFileChange" />
    </div>
    <div
      ref="editorRef"
      class="rte-editor"
      :style="{ minHeight: height }"
      contenteditable="true"
      :placeholder="placeholder"
      @input="handleInput"
    ></div>
  </div>
</template>

<style scoped>
.rte { border: 1px solid var(--el-border-color); border-radius: 4px; }
.rte-toolbar { padding: 6px; border-bottom: 1px solid var(--el-border-color); display: flex; justify-content: space-between; }
.hidden-file { display: none; }
.rte-editor { padding: 10px; line-height: 1.6; }
.rte-editor:empty:before { content: attr(placeholder); color: #999; }
.rte-editor img { max-width: 100%; display: inline-block; }
</style>